/**
  CNOK project, Anyang Normal University, IMP-CAS
  \class TARsMom
  \brief calculate the inclusive momentum distribution of one-nucleon knockout
  residue for intermediate-energy single-nucleon knockout reactions. This is a
  derived class of TARs
  \author SUN Yazhou, asia.rabbit@163.com
  \since 2022/06/21
  \date Last modified: 2022/06/21 by SUN Yazhou
  \copyright 2020-2023 SUN Yazhou
  \copyright CNOK project, Anyang Normal University, IMP-CAS
*/

#include <iostream>
#include <fstream>
#include <iomanip>
#include <cmath>
#include <cstring>
#include "TARsMom.h"
#include "TAParaManager.h"
#include "TAException.h"

using std::ofstream;
using std::cout;
using std::endl;
using std::setw;
using std::setprecision;

TARsMom::TARsMom(int a) : TARs(a, 0., 0., 0., 0.), fNmomc(0){}

// assign the momentum mesh
void TARsMom::AssignKz(int n, const double *kz){
  fNmomc = n; fKz.resize(n); fKz.assign(n,0.);
  for(int i = 0; i < n; i++) fKz[i] = kz[i];
} // end member function AssignKz
// add
void TARsMom::AddConfig(const string &orbit, double ex, double c2s, const double *momstr,
const double *momtot){
  if(ob(orbit)) fOrbit.push_back(orbit);
  else TAException::Error("TARsMom", "AddConfig: illegal input of configuration: %s\
should be of the format \'nlj_Jpi[_No]\'", orbit.c_str());
  fEx.push_back(ex);
  fC2S.push_back(c2s);

  const int n = fNmomc;
  if(!momstr) TAException::Error("TARsMom", "AddConfig: nullptr momstr: %s");
  vector<double> momStr; momStr.resize(n); momStr.assign(n, 0.);
  for(int i = 0; i < n; i++) momStr[i] = momstr[i];
  fMomStr.push_back(momStr);

  if(!momtot) TAException::Error("TARsMom", "AddConfig: nullptr momtot: %s");
  vector<double> momTotal; momTotal.resize(n); momTotal.assign(n, 0.);
  for(int i = 0; i < n; i++) momTotal[i] = momtot[i];
  fMomTotal.push_back(momTotal);
} // end member function AddConfig

// calculate the inclusive momdis
void TARsMom::Mom(){
  const int nn = fOrbit.size();
  fInclStr.resize(fNmomc); fInclTotal.resize(fNmomc);
  fInclStr.assign(fNmomc, 0.); fInclTotal.assign(fNmomc, 0.);
	for(int i = 0; i < nn; i++){
		int n, l, j; char lm;
		sscanf(fOrbit[i].c_str(), "%d%c%d%*s", &n, &lm, &j);
		if(LL.count(lm)) l = LL.at(lm);
		else TAException::Error("TARs", "Rs: orbital momentum notation %c not found", lm);
		int N = 2.*n+l;
    const double cc = pow(fA/(fA-1.), N)*fC2S[i];
		for(int k = 0; k < fNmomc; k++){ // loop over momentum mesh
      fMomStr[i][k] *= cc; fMomTotal[i][k] *= cc;
      fInclStr[k] += fMomStr[i][k]; fInclTotal[k] += fMomTotal[i][k];
    } // end for over k
	} // end for over i

  // print outputs to file //
  char tt[256]{}; strcpy(tt, TAException::time0(true)); // suitable for filename
  char file[1024]; sprintf(file, "%smom.txt", PARA->BaseDir());
  // char file[1024]; sprintf(file, "%smom_%s.txt", PARA->BaseDir(), tt);
  ofstream fout(file); fout << std::setprecision(6) << std::fixed;
	for(int i = 0; i < fNmomc; i++)
    fout << fKz[i] << " " << setw(20) << fInclStr[i] << " " << setw(20) << fInclTotal[i] << endl;
  cout << "The convolved inclusive momentum distribution is written in file " << file;
  cout << ".   file format: kz  str.  tot." << endl;
  fout.close();
} // end member function Mom
